package com.klxedu.ms.gateway.security.access;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.stereotype.Service;

import com.klxedu.ms.gateway.AuthServerConstants;
import com.klxedu.ms.gateway.TenancyConfiguration;

@Service
public class CustomInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {
	private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

	@Autowired
	private IResourceService resourceService;

	/**
	 * 应当是资源为key， 权限为value。 资源通常为url， 权限就是那些以ROLE_为前缀的角色。 一个资源可以由多个权限来访问<br>
	 */
	//@PostConstruct
	private void loadResourceDefine() {
		resourceMap = new HashMap<String, Collection<ConfigAttribute>>();
		Map<String, String[]> allResource = resourceService.findAll();
		if (allResource != null && allResource.size() > 0) {
			Set<Entry<String, String[]>> entrySet = allResource.entrySet();
			for (Iterator<Entry<String, String[]>> iterator = entrySet.iterator(); iterator.hasNext();) {
				Entry<String, String[]> entry = (Entry<String, String[]>) iterator.next();
				List<ConfigAttribute> createList = null;
				// 如果一个资源对应的权限（角色）为空，默认为登录角色。
				if (entry.getValue() == null) {
					createList = new ArrayList<ConfigAttribute>();
					createList.add(new SecurityConfig("IS_AUTHENTICATED_ANONYMOUSLY"));
				} else {
					createList = SecurityConfig.createList(entry.getValue());
				}
				resourceMap.put(entry.getKey(), createList);
			}
		}
	}

	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		FilterInvocation filterInvocation = (FilterInvocation) object;
		//调整mycat多域名问题
		TenancyConfiguration.setTenancy(filterInvocation.getRequest().getHeader(AuthServerConstants.HOST_HEADER_KEY));//设置多租户host
		if (resourceMap == null) {
			loadResourceDefine();
		}
		Iterator<String> ite = resourceMap.keySet().iterator();
		while (ite.hasNext()) {
			String resURL = ite.next();
			String[] split = resURL.split("#");
			RequestMatcher requestMatcher = new AntPathRequestMatcher(split[0]);
			if (requestMatcher.matches(filterInvocation.getHttpRequest())) {
				return resourceMap.get(split[0]+"#"+filterInvocation.getRequest().getMethod());
			}
		}

		return null;
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return new ArrayList<ConfigAttribute>();
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}

}
